#include "myproc.h"
struct __COMMAND  mapaiCommand;
struct __COMMAND  keyCommand;

uint8_t keyOrder = 0; //按键包计数
int16_t memberOrder = 0; //成员的数组位置计数
uint16_t maxMemberItem; //成员的总数，在主函数中获得

//送出去的数据包计算
uint8_t GetKeyOrder(void)
{
    //按键计数，在开始传数据时，置0，然后累加，
    //keyOrder += 1;
    return keyOrder++;
}

//会员当前位置+1
void SetMemberOrderForward(void) 
{
    memberOrder++;
    if(memberOrder >= maxMemberItem) memberOrder = 0;
}

//会员当前位置-1
void SetMemberOrderBack(void)
{
    memberOrder--;
    if(memberOrder < 0) memberOrder = maxMemberItem - 1;
}

//表示是第几组号码
uint16_t GetMemberOrder(void)
{
    //memberOrder全局变量
    uint16_t value = 0;
    value = memberOrder;
    //printf("value=%d, maxMemberItem= %d\n", value, maxMemberItem);
    return value;
}

//分析码牌机过来的数据命令
void AnalysisMAPAICommand(uint8_t *pdat)
{
    uint16_t ii = 0;
    memset(&mapaiCommand, 0, sizeof(mapaiCommand));
    mapaiCommand.head = *(pdat+0);
    mapaiCommand.len = (uint16_t)*(pdat+1);
    mapaiCommand.len <<= 8;
    mapaiCommand.len |= (uint16_t)*(pdat+2);
    mapaiCommand.order = *(pdat+3);
    mapaiCommand.mode = *(pdat+4);
    for(ii=0; ii<mapaiCommand.len; ii++) //有效数据，包括前面包序和类型2个字节，不包含结束符0x03和校验位
    {
        mapaiCommand.dat[ii] = *(pdat+3+ii);
    }
    mapaiCommand.checksum = *(pdat+4+mapaiCommand.len);
    //结束
}

//将ASCLL码转为USBHID键值
uint8_t ConvertASCLL2USBHID(uint8_t keyvalue)
{
    switch (keyvalue)
    {
        case 0x30:
            keyvalue = USBHIDKEY_0;
            break;
        case 0x31:
            keyvalue = USBHIDKEY_1;
            break;
        case 0x32:
            keyvalue = USBHIDKEY_2;
            break;
        case 0x33:
            keyvalue = USBHIDKEY_3;
            break;
        case 0x34:
            keyvalue = USBHIDKEY_4;
            break;
        case 0x35:
            keyvalue = USBHIDKEY_5;
            break;
        case 0x36:
            keyvalue = USBHIDKEY_6;
            break;
        case 0x37:
            keyvalue = USBHIDKEY_7;
            break;
        case 0x38:
            keyvalue = USBHIDKEY_8;
            break;
        case 0x39:
            keyvalue = USBHIDKEY_9;
            break;
        case 0x17:
            keyvalue = USBHIDKEY_CONFIRM;
            break;
        default:
            break;
    }

    return keyvalue;
}

//生成按下USB HID 键值
void GenerateUSBHIDKeyPressMsg(void *msg, uint8_t keyvalue)
{
    MSG *pmsg = (MSG*)msg;
    USBHID usbKey;
    usbKey.head1 = 0x57;
    usbKey.head2 = 0xab;
    usbKey.addr = 0x00;
    usbKey.command = 0x02;
    usbKey.len = 0x08;
    usbKey.dat[0] = 0x00;
    usbKey.dat[1] = 0x00;
    usbKey.dat[2] = ConvertASCLL2USBHID(keyvalue);
    usbKey.dat[3] = 0x00;
    usbKey.dat[4] = 0x00;
    usbKey.dat[5] = 0x00;
    usbKey.dat[6] = 0x00;
    usbKey.dat[7] = 0x00;
    usbKey.sum = usbKey.head1 + usbKey.head2 + usbKey.addr + usbKey.command + usbKey.len\
    +usbKey.dat[0] + usbKey.dat[1] + usbKey.dat[2] + usbKey.dat[3]\
    + usbKey.dat[4] + usbKey.dat[5] + usbKey.dat[6] + usbKey.dat[7];
    pmsg->len = usbKey.len + 6;
    // CP usbhid DAT TO MSG->BUFF
    uint8_t *pusbKey = (uint8_t*)&usbKey;
    for(uint8_t ii=0; ii<(sizeof(USBHID)); ii++)
    {
        pmsg->buff[ii] = *(pusbKey+ii);
    }
}

//生成释放USB HID 键值
void GenerateUSBHIDKeyReleaseMsg(void *msg)
{
    MSG *pmsg = (MSG*)msg;
    USBHID usbKey;
    usbKey.head1 = 0x57;
    usbKey.head2 = 0xab;
    usbKey.addr = 0x00;
    usbKey.command = 0x02;
    usbKey.len = 0x08;
    usbKey.dat[0] = 0x00;
    usbKey.dat[1] = 0x00;
    usbKey.dat[2] = 0x00;
    usbKey.dat[3] = 0x00;
    usbKey.dat[4] = 0x00;
    usbKey.dat[5] = 0x00;
    usbKey.dat[6] = 0x00;
    usbKey.dat[7] = 0x00;
    usbKey.sum = usbKey.head1 + usbKey.head2 + usbKey.addr + usbKey.command + usbKey.len\
    +usbKey.dat[0] + usbKey.dat[1] + usbKey.dat[2] + usbKey.dat[3]\
    + usbKey.dat[4] + usbKey.dat[5] + usbKey.dat[6] + usbKey.dat[7];
    pmsg->len = usbKey.len + 6;
    // CP usbhid DAT TO MSG->BUFF
    uint8_t *pusbKey = (uint8_t*)&usbKey;
    for(uint8_t ii=0; ii<(sizeof(USBHID)); ii++)
    {
        pmsg->buff[ii] = *(pusbKey+ii);
    }
}

//发送USB HID键盘数据
void TransferUSBHIDKey(void *msg, uint8_t keyvalue)
{
    GenerateUSBHIDKeyPressMsg(msg, keyvalue);
    USBHIDtransferDat(msg);
    usleep(15000);
    GenerateUSBHIDKeyReleaseMsg(msg);
    USBHIDtransferDat(msg);
    if(keyvalue == 0x17) //是确认键
    usleep(700000);
    else 
    usleep(20000);

}

//用7步生成 <序号，版本> 数据
void GenerateVersionMsg(void *msg) //用7步生成 <序号，版本> 数据
{
//   02  |  00 0A   |   04   | 16    | AC 6E 1E 90 0F C7 9A D0  |  03   |   D5   |     码牌机发过来的数据
//   ====|==========|========|=======|==========================| ===   |======= |
//   开始 | 字节长度 |  包序   | 类型  |                数据      |  结束  |  校验位 | 

//   06 02 |  00 0D  |  00 |  1A   | 00 00 4B 42 44 5F 56 |  32 2E 30 31 |   03 |  4D   |   键盘响应的数据
//   ======|=========|=====|=======|======================|==============|======|=======|
//   开始  | 字节长度 | 包序 | 类型  |      数据            |  版本号       | 结束 | 校验位 | 
//     0        1        2     3           4                   5             6      7       
    MSG *pmsg = (MSG*)msg;
    uint8_t *pbuff = ((MSG*)msg)->buff; 
    uint8_t sn[7] = {0x00, 0x00, 0x4B, 0x42, 0x44, 0x5F, 0x56};//KBD_V
    uint8_t ver[4] = {0x32, 0x2E, 0x30, 0x31}; //2.01
    uint8_t stepStatus = 0;
    uint16_t iCount = 0; //用于计数，写入数据的长度，写一个数据+1
    while(stepStatus <= 7) //用7步生成 <序号，版本> 数据
    {
        if(iCount >= MSGBUFFSIZE)
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch (stepStatus)
        {
            case 0: //head 
                *(pbuff+iCount) = 0x06;
                iCount++;
                *(pbuff+iCount) = 0x02;
                iCount++;
                stepStatus = 1;
                break;

            case 1: // msg len
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x0D;
                iCount++;
                stepStatus = 2;
                break;

            case 2: // order
                *(pbuff+iCount) = mapaiCommand.order;
                iCount++;
                stepStatus = 3;
                break;

            case 3: //mode
                *(pbuff+iCount) = mapaiCommand.mode;
                iCount++;
                stepStatus = 4;
                break;

            case 4: // data
                for(uint8_t ii=0; ii<sizeof(sn); ii++)
                {
                    *(pbuff+iCount) = sn[ii];
                    iCount++;
                }
                stepStatus = 5;
                break;
            
            case 5: //version
                for(uint8_t ii=0; ii<sizeof(ver); ii++)
                {
                    *(pbuff+iCount) = ver[ii];
                    iCount++;
                }
                stepStatus = 6;
                break;
            
            case 6: // end byte
                *(pbuff+iCount) = 0x03;
                iCount++;
                stepStatus = 7;
                break;
            
            case 7: //checksum
                uint8_t xorsum = 0;
                for(uint16_t ii=0; ii<iCount; ii++)
                {
                    xorsum ^= *(pbuff+ii);
                }
                xorsum ^= 0x04;
                *(pbuff+iCount) = xorsum;
                iCount++;
                pmsg->len = iCount;
                stepStatus = 8; //结束SWITCH循环
                break;

            default:
                stepStatus = 0;
                break;                
        } //switch end
    } // while end
}

//用6步生成 <按键响应> 数据
void GenerateKeyReplyMsg(void *msg) //用6步生成 <按键响应> 数据
{
//   06 02 |  00 04  |  00 |  1C   |        00 00         |   03 |  4D   |   键盘响应的数据
//   ======|=========|=====|=======|======================|======|=======|
//   开始  | 字节长度 | 包序 | 类型  |      数据            | 结束  | 校验位 | 
//     0        1        2     3           4                  5      6    
    MSG *pmsg = (MSG*)msg;
    uint8_t *pbuff = ((MSG*)msg)->buff;
    uint8_t dat[2] = {0x00, 0x00};
    uint8_t stepStatus = 0;
    uint16_t iCount = 0; //用于计数，写入数据的长度，写一个数据+1
    while(stepStatus <= 6) //用 6 步生成 <初始化> 数据
    {
        if(iCount >= MSGBUFFSIZE)
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch (stepStatus)
        {
            case 0: //head 
                *(pbuff+iCount) = 0x06;
                iCount++;
                *(pbuff+iCount) = 0x02;
                iCount++;
                stepStatus = 1;
                break;

            case 1: // msg len
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x04;
                iCount++;
                stepStatus = 2;
                break;

            case 2: // order
                *(pbuff+iCount) = mapaiCommand.order;
                iCount++;
                stepStatus = 3;
                break;

            case 3: //mode
                *(pbuff+iCount) = mapaiCommand.mode;
                iCount++;
                stepStatus = 4;
                break;

            case 4: // data
                for(uint8_t ii=0; ii<sizeof(dat); ii++)
                {
                    *(pbuff+iCount) = dat[ii];
                    iCount++;
                }
                stepStatus = 5;
                break;
            
            case 5: // end byte
                *(pbuff+iCount) = 0x03;
                iCount++;
                stepStatus = 6;
                break;
            
            case 6: //checksum
                uint8_t xorsum = 0;
                for(uint16_t ii=0; ii<iCount; ii++)
                {
                    xorsum ^= *(pbuff+ii);
                }
                xorsum ^= 0x04;
                *(pbuff+iCount) = xorsum;
                iCount++;
                pmsg->len = iCount;
                stepStatus = 7; //结束SWITCH循环
                break;

            default:
                stepStatus = 0;
                break;                
        } //switch end
    } // while end
}


//用6步生成 <初始化> 数据
void GenerateInitMsg(void *msg) //用6步生成 <初始化> 数据
{
//   06 02 |  00 04  |  00 |  1C   |        00 00         |   03 |  4D   |   键盘响应的数据
//   ======|=========|=====|=======|======================|======|=======|
//   开始  | 字节长度 | 包序 | 类型  |      数据            | 结束  | 校验位 | 
//     0        1        2     3           4                  5      6    
    MSG *pmsg = (MSG*)msg;
    uint8_t *pbuff = ((MSG*)msg)->buff;
    uint8_t dat[2] = {0x00, 0x00};
    uint8_t stepStatus = 0;
    uint16_t iCount = 0; //用于计数，写入数据的长度，写一个数据+1
    while(stepStatus <= 6) //用 6 步生成 <初始化> 数据
    {
        if(iCount >= MSGBUFFSIZE)
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch (stepStatus)
        {
            case 0: //head 
                *(pbuff+iCount) = 0x06;
                iCount++;
                *(pbuff+iCount) = 0x02;
                iCount++;
                stepStatus = 1;
                break;

            case 1: // msg len
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x04;
                iCount++;
                stepStatus = 2;
                break;

            case 2: // order
                *(pbuff+iCount) = mapaiCommand.order;
                iCount++;
                stepStatus = 3;
                break;

            case 3: //mode
                *(pbuff+iCount) = mapaiCommand.mode;
                iCount++;
                stepStatus = 4;
                break;

            case 4: // data
                for(uint8_t ii=0; ii<sizeof(dat); ii++)
                {
                    *(pbuff+iCount) = dat[ii];
                    iCount++;
                }
                stepStatus = 5;
                break;
            
            case 5: // end byte
                *(pbuff+iCount) = 0x03;
                iCount++;
                stepStatus = 6;
                break;
            
            case 6: //checksum
                uint8_t xorsum = 0;
                for(uint16_t ii=0; ii<iCount; ii++)
                {
                    xorsum ^= *(pbuff+ii);
                }
                xorsum ^= 0x04;
                *(pbuff+iCount) = xorsum;
                iCount++;
                pmsg->len = iCount;
                stepStatus = 7; //结束SWITCH循环
                break;

            default:
                stepStatus = 0;
                break;                
        } //switch end
    } // while end
}

//用6步生成 <周期应答> 数据
void GeneratePeriodResponseMsg(void *msg) //用6步生成 <周期应答> 数据
{
//   06 02 |  00 0C  |  04 |  16   | 00 00 F6 22 80 0F 90 8A C2 A9  |   03 |  4D   |   键盘响应的数据
//   ======|=========|=====|=======|================================|======|=======|
//   开始  | 字节长度 | 包序 | 类型  |            数据                | 结束  | 校验位 | 
//     0        1        2     3                 4                      5      6    

    MSG *pmsg = (MSG*)msg;
    uint8_t *pbuff = ((MSG*)msg)->buff;
    uint8_t stepStatus = 0;
    uint16_t iCount = 0; //用于计数，写入数据的长度，写一个数据+1
    while(stepStatus <= 6) //用 6 步生成 <初始化> 数据
    {
        if(iCount >= MSGBUFFSIZE)
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch (stepStatus)
        {
            case 0: //head 
                *(pbuff+iCount) = 0x06;
                iCount++;
                *(pbuff+iCount) = 0x02;
                iCount++;
                stepStatus = 1;
                break;

            case 1: // msg len
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x0C;
                iCount++;
                stepStatus = 2;
                break;

            case 2: // order
                *(pbuff+iCount) = mapaiCommand.order;
                iCount++;
                stepStatus = 3;
                break;

            case 3: //mode
                *(pbuff+iCount) = mapaiCommand.mode;
                iCount++;
                stepStatus = 4;
                break;

            case 4: // data
                *(pbuff+iCount) = 0x00; //前2字节填充0x00,0x00
                iCount++;
                *(pbuff+iCount) = 0x00;
                iCount++;
                for(uint8_t ii=0; ii<mapaiCommand.len-2; ii++)
                {
                    *(pbuff+iCount) = mapaiCommand.dat[2+ii];
                    iCount++;
                }
                stepStatus = 5;
                break;
            
            case 5: // end byte
                *(pbuff+iCount) = 0x03;
                iCount++;
                stepStatus = 6;
                break;
            
            case 6: //checksum
                uint8_t xorsum = 0;
                for(uint16_t ii=0; ii<iCount; ii++)
                {
                    xorsum ^= *(pbuff+ii);
                }
                xorsum ^= 0x04;
                *(pbuff+iCount) = xorsum;
                iCount++;
                pmsg->len = iCount;
                stepStatus = 7; //结束SWITCH循环
                break;

            default:
                stepStatus = 0;
                break;                
        } //switch end
    } // while end
}

//生成 <按键 按下> 数据
void GenerateKeyPressMsg(void *msg, uint8_t key) //生成 <按键 按下> 数据
{
//   02    |  00 06  |  05 |  A3   |   00 00 01 1F   |   03 |  4D   |   数据第三字节01:按下， 00：释放
//   ======|=========|=====|=======|=================|======|=======|   数据第四字节1F 键值
//   开始  | 字节长度 | 包序 | 类型  |         数据    | 结束  | 校验位 | 
//     0        1        2     3              4          5      6    

    MSG *pmsg = (MSG*)msg;
    uint8_t *pbuff = ((MSG*)msg)->buff;
    uint8_t stepStatus = 0;
    uint16_t iCount = 0; //用于计数，写入数据的长度，写一个数据+1
    while(stepStatus <= 6) //用 6 步生成 <按键> 数据
    {
        if(iCount >= MSGBUFFSIZE)
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch (stepStatus)
        {
            case 0: //head 
                *(pbuff+iCount) = 0x02;
                iCount++;
                stepStatus = 1;
                break;

            case 1: // msg len
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x06;
                iCount++;
                stepStatus = 2;
                break;

            case 2: // order
                *(pbuff+iCount) = GetKeyOrder();
                iCount++;
                stepStatus = 3;
                break;

            case 3: //mode
                *(pbuff+iCount) = 0xA3;
                iCount++;
                stepStatus = 4;
                break;

            case 4: // data
                *(pbuff+iCount) = 0x00; //前2字节填充0x00,0x00
                iCount++;
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x01; //键按下 0x01, 松开0x00
                iCount++;
                *(pbuff+iCount) = key; //键值
                iCount++;
                stepStatus = 5;
                break;
            
            case 5: // end byte
                *(pbuff+iCount) = 0x03;
                iCount++;
                stepStatus = 6;
                break;
            
            case 6: //checksum
                uint8_t xorsum = 0;
                for(uint16_t ii=0; ii<iCount; ii++)
                {
                    xorsum ^= *(pbuff+ii);
                }
                xorsum ^= 0x02;
                *(pbuff+iCount) = xorsum;
                iCount++;
                pmsg->len = iCount;
                stepStatus = 7; //结束SWITCH循环
                break;

            default:
                stepStatus = 0;
                break;                
        } //switch end
    } // while end
}


//生成 <按键 松开> 数据
void GenerateKeyReleaseMsg(void *msg, uint8_t key) //生成 <按键 松开> 数据
{
//   02    |  00 06  |  05 |  A3   |   00 00 00 1F   |   03 |  4D   |   数据第三字节01:按下， 00：释放
//   ======|=========|=====|=======|=================|======|=======|   数据第四字节1F 键值
//   开始  | 字节长度 | 包序 | 类型  |         数据    | 结束  | 校验位 | 
//     0        1        2     3              4          5      6   

    MSG *pmsg = (MSG*)msg;
    uint8_t *pbuff = ((MSG*)msg)->buff;
    uint8_t stepStatus = 0;
    uint16_t iCount = 0; //用于计数，写入数据的长度，写一个数据+1
    while(stepStatus <= 6) //用 6 步生成 <按键> 数据
    {
        if(iCount >= MSGBUFFSIZE)
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch (stepStatus)
        {
            case 0: //head 
                *(pbuff+iCount) = 0x02;
                iCount++;
                stepStatus = 1;
                break;

            case 1: // msg len
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x06;
                iCount++;
                stepStatus = 2;
                break;

            case 2: // order
                *(pbuff+iCount) = GetKeyOrder();
                iCount++;
                stepStatus = 3;
                break;

            case 3: //mode
                *(pbuff+iCount) = 0xA3;
                iCount++;
                stepStatus = 4;
                break;

            case 4: // data
                *(pbuff+iCount) = 0x00; //前2字节填充0x00,0x00
                iCount++;
                *(pbuff+iCount) = 0x00;
                iCount++;
                *(pbuff+iCount) = 0x00; //键按下 0x01, 松开0x00
                iCount++;
                *(pbuff+iCount) = key; //键值
                iCount++;
                stepStatus = 5;
                break;
            
            case 5: // end byte
                *(pbuff+iCount) = 0x03;
                iCount++;
                stepStatus = 6;
                break;
            
            case 6: //checksum
                uint8_t xorsum = 0;
                for(uint16_t ii=0; ii<iCount; ii++)
                {
                    xorsum ^= *(pbuff+ii);
                }
                xorsum ^= 0x02;
                *(pbuff+iCount) = xorsum;
                iCount++;
                pmsg->len = iCount;
                stepStatus = 7; //结束SWITCH循环
                break;

            default:
                stepStatus = 0;
                break;                
        } //switch end
    } // while end
}
// //解析数据
// uint16_t AnalysisBillData(uint8_t *pdat, BILLINFO *pbill)
// {
//     //pbill->pBuff = pdat;
//     return 0;
// }

//判断是否是退货单， 0=不是  1=是
uint8_t IsReturnBill(uint8_t *pdat)
{
    uint16_t iCount = 0;
    uint8_t stepStatus = 0;
    uint8_t isExsit = 0;
    while(stepStatus < 3)
    {
        if((iCount+7) >=TTYS1RXBUFFSIZE) 
        {
            break;
        }
        switch(stepStatus)
        {
            case 0: //初始化，准备就绪
                iCount = 0;
                stepStatus = 1;
                isExsit = 0;
                break;
            case 1: //查找特定的字符 GB2312编码 "退货单**"
                if((*(pdat+iCount) == 0xCD) && (*(pdat+iCount+1) == 0xCB) && \
                (*(pdat+iCount+2) == 0xBB) && (*(pdat+iCount+3) == 0xF5) && \
                (*(pdat+iCount+4) == 0xB5) && (*(pdat+iCount+5) == 0xA5) && \
                (*(pdat+iCount+6) == 0x2A) && (*(pdat+iCount+7) == 0x2A))
                {
                    isExsit = 1;
                    stepStatus = 2;
                }
                iCount++;
                break;
            case 2:
                stepStatus = 3;
                break;
            default:
                break;
        
        }// SWITCH END

    } // WHILE END

    return isExsit; //返回结果
} //FUNCATION END


//获取小票数据中的物品信息合计
uint16_t GetBillTotalItem(uint8_t *pdat)
{ 
    uint16_t iCount=0;
    uint8_t stepStatus = 0;
    int8_t ascllbuff[7];
    uint16_t ascllbuffOffset=0;
    uint16_t itemCount=0;
  //  printf("GetToalItem running...\n");
    while(stepStatus<4) //5步完成数据检索
    {
        if(iCount >=TTYS1RXBUFFSIZE) 
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d data scan complete. iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch(stepStatus)
        {
            case 0: //初始化，准备就绪
           // printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
                iCount = 0;
                ascllbuffOffset = 0;
                itemCount = 0;
                memset(ascllbuff, 0, sizeof(ascllbuff));
                stepStatus = 1;              
                break;
            case 1: // search and locate  //合计:
               // printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
                if((*(pdat+iCount) == 0xBA) && (*(pdat+iCount+1) == 0xCF) && \
                (*(pdat+iCount+2) == 0xBC) && (*(pdat+iCount+3) == 0xC6) && \
                (*(pdat+iCount+4) == 0x3A))
                { // FIND “合计:”字符
            //        printf("GetToalItem: find flag!\n");
                    iCount +=4;
                    stepStatus = 2;
                }
                iCount++;
                break;
            case 2: //copy valid data
                if((*(pdat+iCount)) == 0x20) //有空格就跳过空格
                {
                    iCount++;
                    break;
                }
               // if((*(pdat+iCount+1) == 0x20)) stepStatus = 3; //下一个字符为空格时，意味着数据结束，跳转下一步骤
                if((*(pdat+iCount+1) < 0x30) || (*(pdat+iCount+1) > 0x39)) stepStatus = 3;
              //  printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
              //  printf("GetTotalItem: copy valid data...\n");
                ascllbuff[ascllbuffOffset] = *(pdat+iCount);             
                ascllbuffOffset++;
                iCount++;
                break;
            case 3://process the data, and reset stepstatus
          //  printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
            // printf("item raw data: ");
            //     for(int ii=0; ii<7;ii++)
            //     {
            //         printf("%2x ", ascllbuff[ii]);
            //     }
            //     printf("\n");
            //     printf("GetTotalItem: atoi...\n");
                itemCount = atoi((const char*)ascllbuff);
                stepStatus = 4;
                break;
            case 4: //
                stepStatus = 0;
                break;
            default:
                break;
        } // switch end
    } // while end
    return itemCount; //返回小票中的条码合计
}

//获取小票信息中总金额
double GetBillTotalPrice(uint8_t *pdat)
{
    uint16_t iCount=0;
    uint8_t stepStatus = 0;
    int8_t ascllbuff[7];
    uint16_t ascllbuffOffset=0;
    double totalPrice = 0;
   // printf("GetToalItem running...\n");
    while(stepStatus<4) //5步完成数据检索
    {
        if(iCount >=TTYS1RXBUFFSIZE) 
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d scan complete. iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch(stepStatus)
        {
            case 0: //初始化，准备就绪
           // printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
                iCount = 0;
                ascllbuffOffset = 0;
                totalPrice = 0;
                memset(ascllbuff, 0, sizeof(ascllbuff));
                stepStatus = 1;              
                break;
            case 1: // search and locate  
               // printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
                if((*(pdat+iCount) == 0xD3) && (*(pdat+iCount+1) == 0xA6) && \
                (*(pdat+iCount+2) == 0xCA) && (*(pdat+iCount+3) == 0xD5) && \
                (*(pdat+iCount+4) == 0xBD) && (*(pdat+iCount+5) == 0xF0) && \
                (*(pdat+iCount+6) == 0xB6) && (*(pdat+iCount+7) == 0xEE) && \
                (*(pdat+iCount+8) == 0x3A))
                { // FIND “应收金额:”字符
               //     printf("GetToalItem: find flag!\n");
                    iCount +=8;
                    stepStatus = 2;
                }
                iCount++;
                break;
            case 2: //copy valid data
                if((*(pdat+iCount)) == 0x20) //有空格就跳过空格
                {
                    iCount++;
                    break;
                }
                //if((*(pdat+iCount+1) == 0x0A)) stepStatus = 3; //下一个字符为空格时，意味着数据结束，跳转下一步骤
                if((*(pdat+iCount+1) < 0x30) || (*(pdat+iCount+1) > 0x39)) 
                {
                    if(*(pdat+iCount+1) != 0x2E) stepStatus = 3;
                }
              //  printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
              //  printf("GetTotalItem: copy valid data...\n");
                ascllbuff[ascllbuffOffset] = *(pdat+iCount);             
                ascllbuffOffset++;
                iCount++;
                break;
            case 3://process the data, and reset stepstatus
          //  printf("GetToalItem: stepStatus: %d, iCount: %d\n", stepStatus, iCount);
                // printf("Price raw data: ");
                // for(int ii=0; ii<7;ii++)
                // {
                //     printf("%2x ", ascllbuff[ii]);
                // }
                // printf("\n");
                totalPrice = atof((const char*)ascllbuff);
               // printf("GetTotalPrice: atof... price: %.2f\n", totalPrice);
                stepStatus = 4;
                break;
            case 4: //
                stepStatus = 0;
                break;
            default:
                break;
        } // switch end
    } // while end
    return totalPrice; //返回小票中的金额合计
}

//获取小票信息，序号，条码，数量，小计, 
//通过BILLINFO *pbill保存数据
//返回小票内容总条码数
uint16_t GetBillEan13Code(uint8_t *pdat, BILLINFO *pbill)
{
    uint16_t iCount = 0;
    uint8_t stepStatus = 0;
    int8_t ean13buff[15];
    uint16_t ean13buffOffset=0;
    int8_t numbuff[3];
    uint16_t numbuffOffset=0;
    int8_t quantitybuff[3];
    uint16_t quantitybuffoffset=0;
    int8_t subtotalbuff[8];
    uint16_t subtotalbuffoffset=0;
    uint8_t spaceCount = 0;
    uint8_t totalNumbers = 0;
    int8_t namestrbuff[32];
    uint16_t namestrbuffoffset = 0;
    while(stepStatus < 17)
    {
        if(iCount >=TTYS1RXBUFFSIZE) 
        {
            stepStatus = 0; //超出缓冲区
            printf("%s:%d scan complete. iCount point overflow!\n", __func__, __LINE__);
            break;
        }
        switch(stepStatus)
        {
            case 0: //初始化
                spaceCount = 0;
                iCount = 0;
                totalNumbers = 0;
                memset(ean13buff, 0, sizeof(ean13buff));
                ean13buffOffset = 0;
                memset(numbuff, 0, sizeof(numbuff));
                numbuffOffset = 0;
                memset(quantitybuff, 0, sizeof(quantitybuff));
                quantitybuffoffset = 0;
                memset(subtotalbuff, 0, sizeof(subtotalbuff));
                subtotalbuffoffset = 0;
                memset(namestrbuff, 0, sizeof(namestrbuff));
                namestrbuffoffset = 0;
                stepStatus = 1;
                break;
            case 1: //定位条码数据开始处
                if((*(pdat+iCount) == 0x2D) && (*(pdat+iCount+1) == 0x2D) && \
                (*(pdat+iCount+2) == 0x2D) && (*(pdat+iCount+3) == 0x2D) && \
                (*(pdat+iCount+4) == 0x2D) && (*(pdat+iCount+5) == 0x2D) && \
                (*(pdat+iCount+6) == 0x2D) && (*(pdat+iCount+7) == 0x2D) && \
                (*(pdat+iCount+8) == 0x0A))
                { // FIND “-------------0x0A”字符
               //     printf("GetBillEan13Code: find flag!\n");
                    iCount +=8;
                    stepStatus = 2;
                }
                iCount++;
                break;
            case 2: //准备获取小票条码的前序号 1 ... 2 ... 3
                if((*(pdat+iCount)  < 0x30) || (*(pdat+iCount) > 0x39)) //非数字
                {
                    ////printf("%s, %d: data buff formats error!\n", __FILE__, __LINE__);
                    iCount++;
                    break;
                }
                ////printf("stepStatus: %d, dat: %2x, next dat: %2x\n", stepStatus, *(pdat+iCount), *(pdat+iCount+1));
                numbuff[numbuffOffset] = *(pdat+iCount);
                if((*(pdat+iCount+1)  < 0x30) || (*(pdat+iCount+1) > 0x39)) //当前位置的下一个字符不是数字
                {
                    stepStatus = 3;
                }
                iCount++;
                numbuffOffset++;
                break;                              
            case 3:// numbuff[numbuffOffset] 已保存了序号，打印序号
                // printf("number: ");
                // for(uint16_t ii=0; ii<numbuffOffset; ii++)
                // {
                //     //printf("%2x ", numbuff[ii]);
                // }
                // printf("\n");
                totalNumbers++; //小票内容条目总数+1
                pbill->itemInfo[atoi((const char*)numbuff)-1].serialNum = atoi((const char*)numbuff);
                stepStatus = 4;
                break;
            case 4: //准备获取条码
                if((*(pdat+iCount)  < 0x30) || (*(pdat+iCount) > 0x39)) //跳过序号到条码之间的所有非数字的字符
                { //跳过下一个数字前的所有非数字字符
                    iCount++;
                    break;
                }
                ean13buff[ean13buffOffset] = *(pdat+iCount);
                if((*(pdat+iCount+1)  < 0x30) || (*(pdat+iCount+1) > 0x39)) //当前指针的下一个字符不是数字
                {//条码读取完成
                    stepStatus = 5;
                }
                iCount++;
                ean13buffOffset++;
                break;
            case 5: // ean13buff[ean13buffOffset] 已保存了条码，打印条码
                //printf("ean13code: ");
                for(uint16_t ii=0; ii<ean13buffOffset; ii++)
                {
                    //printf("%2x ", ean13buff[ii]);
                    pbill->itemInfo[atoi((const char*)numbuff)-1].ean13Code[ii] = ean13buff[ii];
                }
                stepStatus = 6;
                break;
            case 6://跳过小票上条码后面的所有字符
                if((*(pdat+iCount)  == 0x0A)) //跳过后续的字符，在下一状态时，指针指向下一行首
                {//当前行结束
                    stepStatus = 7;
                }
                if((*(pdat+iCount)  != 0x0A)) 
                { //当前字符不是0x0a, 保存起来
                    pbill->itemInfo[atoi((const char*)numbuff)-1].nameStr[namestrbuffoffset] = *(pdat+iCount);
                
                }
                namestrbuffoffset++;
                iCount++;
                break;
            case 7: //准备读取规格、数量、单价、小计一行的内容
                if((*(pdat+iCount)  == 0x20)) //如果是空格  0x20
                {
                    spaceCount++;
                    if(spaceCount >= 10) 
                    {//连续10个空格，视为规格栏为空，跳过所有空格并进入下一个状态读取数量信息
                       if((*(pdat+iCount+1) >= 0x30) && (*(pdat+iCount+1) <= 0x39))
                        {//发现下一个字符是数字字符，意味着数量数据开始
                           stepStatus =8; //进入规格栏的处理
                        }        
                    }
                    iCount++;
                    break;
                }
                else 
                {//如果不是空格 0x20
                    spaceCount = 0;
                    if((*(pdat+iCount+1) == 0x20) &&\
                    (*(pdat+iCount+2) == 0x20) &&\
                    (*(pdat+iCount+3) == 0x20) &&\
                    (*(pdat+iCount+4) == 0x20))
                    {//非空格符后，至少连续4个空格符，认为规格栏结束，进入下一状态
                        stepStatus =8; //进入规格栏的处理     
                    }
                    iCount++;
                    break;
                }       
                break;       
            case 8: //读取数量
                if((*(pdat+iCount)  < 0x30) || (*(pdat+iCount) > 0x39)) //跳过所有非数字的字符
                { //跳过下一个数字前的所有非数字字符
                    iCount++;
                    break;
                }
                quantitybuff[quantitybuffoffset] = *(pdat+iCount);
                if((*(pdat+iCount+1)  < 0x30) || (*(pdat+iCount+1) > 0x39)) //当前指针的下一个字符不是数字
                {//条码读取完成
                    stepStatus = 9;
                }
                iCount++;
                quantitybuffoffset++;
                break;
            case 9: //quantitybuff[quantitybuffoffset]已保存了数量信息
            //printf("stepStatus: %d\n", stepStatus);
                // printf("quantity[]: ");
                // for(uint16_t ii=0; ii<quantitybuffoffset; ii++)
                // {
                //     printf("%2x ", quantitybuff[ii]);
                // }
                // printf("\n");

                pbill->itemInfo[atoi((const char*)numbuff)-1].quantity = atoi((const char*)quantitybuff);
                stepStatus = 10;
                break;
            
            case 10://找到本行0X0A符
            ////printf("stepStatus: %d\n", stepStatus);
                if(*(pdat+iCount+1)  == 0x0A)
                {
                    stepStatus = 11;
                }
                iCount++;
                break;
            case 11://找到本行0x0A前的第一个空格符0x20
            ////printf("stepStatus: %d\n", stepStatus);
                if(*(pdat+iCount-1)  == 0x20)
                {
                    stepStatus = 12;
                }
                iCount--;
                break;
            case 12: //读取小计数据
                if((*(pdat+iCount) < 0x30) || (*(pdat+iCount) > 0x39))
                {
                    if(*(pdat+iCount) != 0x2E)
                    {
                        iCount++;
                        break;
                    }
                }
                subtotalbuff[subtotalbuffoffset] = *(pdat+iCount);
                if((*(pdat+iCount+1) < 0x30) || (*(pdat+iCount+1) > 0x39))
                {
                    if(*(pdat+iCount+1) != 0x2E) stepStatus = 13;
                }
                iCount++;
                subtotalbuffoffset++;
                break;
            case 13://subtotalbuff[subtotalbuffoffset] 已保存小计数据，打印
                //printf("subtotal: ");
                // for(uint16_t ii=0; ii<subtotalbuffoffset; ii++)
                // {
                //     //printf("%2x ", subtotalbuff[ii]);
                // }
                //printf("\n");
                pbill->itemInfo[atoi((const char*)numbuff)-1].subTotal = atof((const char*)subtotalbuff);
                stepStatus = 14;
                break;
            case 14: //清除ean13buff, numbuff数组的数据
                memset(ean13buff, 0, sizeof(ean13buff));
                ean13buffOffset = 0;
                memset(numbuff, 0, sizeof(numbuff));
                numbuffOffset = 0;
                memset(quantitybuff, 0, sizeof(quantitybuff));
                quantitybuffoffset = 0;
                memset(subtotalbuff, 0, sizeof(subtotalbuff));
                subtotalbuffoffset = 0;
                memset(namestrbuff, 0, sizeof(namestrbuff));
                namestrbuffoffset = 0;
                spaceCount = 0; //将下一状态中，空格计数器清零
                stepStatus = 15;
                break;
            case 15: //是否还有新的条码或者结束
                if((*(pdat+iCount+1) == 0x2D) && (*(pdat+iCount+2) == 0x2D))
                { //对当前位置下一个数据和下一个数据判断是否是--(0x2d),是，认为结束
                    stepStatus = 17;
                }
                else if((*(pdat+iCount+1) >= 0x30) && (*(pdat+iCount+1) <= 0x39)) //当前是数字
                {//当前位置的下一个字符是否是数字
                    stepStatus = 2;  //新数据重新开始   数字勿修改
                }
                else 
                {   
                    
                    stepStatus = 16; 
                }
                iCount++;
                break;
            
            case 16:
                if(*(pdat+iCount) == 0x0A)
                {
                    if((*(pdat+iCount+1) == 0x2D) && (*(pdat+iCount+2) == 0x2D))
                    { //对当前位置下一个数据和下下一个数据判断是否是--(0x2d),是，认为结束
                        stepStatus = 17;
                    }
                    else if((*(pdat+iCount+1) >= 0x30) && (*(pdat+iCount+1) <= 0x39)) //当前是数字
                    {//当前位置是否是数字
                        stepStatus = 2;  //新数据重新开始   数字勿修改
                    }else 
                    {
                        stepStatus = 17;//结束while循环
                    }
                }               
                iCount++;
                break;
            default:
                break;

        } // switch end
    } // while end
    //printf("Analysis terminal!\n\n\n\n");
    return totalNumbers;
}

//读取文件转换到相应的结构体中
YANINFO *ConvertFile2Struc(int8_t *pbuff, off_t size, size_t totalItem)
{
    uint16_t item = 0;
    uint8_t stepStatus = 0;
    uint8_t eanoffset = 0;
    uint8_t priceoffset = 0;
    off_t buffoffset = 0;
    size_t mallocSize = (sizeof(YANINFO)) * totalItem;
    YANINFO *pyaninfo = NULL;
    pyaninfo = (YANINFO (*))malloc(mallocSize);
    if(pyaninfo == NULL) 
    {
        printf("malloc yaninfo failse!\n");
        return 0;
    }
    memset(pyaninfo, 0, (sizeof(YANINFO) * totalItem)); 
    while((stepStatus < 4) && (buffoffset < size)) //将数据写入结构体中
    {
        switch(stepStatus)
        {
            case 0: //初始化
                eanoffset = 0;
                priceoffset = 0;
                stepStatus = 1;
                break;
            case 1: //读条码
                if(*(pbuff+buffoffset) == 0x0A)
                {
                    buffoffset++;
                    break; 
                }
                if((*(pbuff+buffoffset) >= '0') && (*(pbuff+buffoffset) <= '9'))
                {
                    if(eanoffset < 13) //防越界，条码小于13位
                    {
                     (pyaninfo+item)->ean13[eanoffset] = *(pbuff+buffoffset);
                     eanoffset++;
                    }
                    
                    
                }
                if(*(pbuff+buffoffset) == ',')
                {
                    stepStatus = 2;
                   
                }
                
                buffoffset++;
                
                break;
            case 2: //读价格
                if(((*(pbuff+buffoffset) >= '0') && (*(pbuff+buffoffset) <= '9')) || (*(pbuff+buffoffset) == '.'))
                {
                    if(priceoffset < 7) //防越界，价格小于7位
                    {
                    (pyaninfo+item)->price[priceoffset] = *(pbuff+buffoffset);
                    
                    priceoffset++;
                    }
                }
                if(*(pbuff+buffoffset) == ',') //读取到价格数据后面的,号，
                {
                    stepStatus = 3;               
                }
                
                buffoffset++;
                break;
            case 3://读备注
                if((*(pbuff+buffoffset) == 0x0A))
                {
                    if((buffoffset+1) < size) //不是文件尾
                    {
                        if((*(pbuff+buffoffset+1) >= '0') && (*(pbuff+buffoffset+1) <= '9'))
                        { //下一个字符是0x0A,再下一个字符是数字，认为还有新数据
                            
                            stepStatus = 0;
                            item++;         
                        }
                    }

                }
                buffoffset++;
                break;
            default:
                break;

        } //switch end
    } // while end
    item++;
    return pyaninfo;
}

//读取烟文件中的条码数量
uint16_t GetYanFileItem(int8_t *pbuff, off_t size)
{
    uint16_t item = 0;
    uint8_t stepStatus = 0;
    uint8_t eanoffset = 0;
    uint8_t priceoffset = 0;
    off_t buffoffset = 0;
    while((stepStatus < 4) && (buffoffset < size)) //将数据写入结构体中
    {
        switch(stepStatus)
        {
            case 0: //初始化
                eanoffset = 0;
                priceoffset = 0;
                stepStatus = 1;
                break;
            case 1: //读条码
                if(*(pbuff+buffoffset) == 0x0A)
                {
                    buffoffset++;
                    break; 
                }
                if((*(pbuff+buffoffset) >= '0') && (*(pbuff+buffoffset) <= '9'))
                {
                    eanoffset++;
                }
                if(*(pbuff+buffoffset) == ',')
                {
                    stepStatus = 2;   
                }
                
                buffoffset++;
                
                break;
            case 2: //读价格
                if(((*(pbuff+buffoffset) >= '0') && (*(pbuff+buffoffset) <= '9')) || (*(pbuff+buffoffset) == '.'))
                {
                    priceoffset++;
                }
                if(*(pbuff+buffoffset) == ',') //读取到价格数据后面的,号，
                {
                    stepStatus = 3;               
                }
                
                buffoffset++;
                break;
            case 3://读备注
                if((*(pbuff+buffoffset) == 0x0A))
                {
                    if((buffoffset+1) < size) //不是文件尾
                    {
                        if((*(pbuff+buffoffset+1) >= '0') && (*(pbuff+buffoffset+1) <= '9'))
                        { //下一个字符是0x0A,再下一个字符是数字，认为还有新数据       
                            stepStatus = 0;
                            item++;         
                        }
                    }
                }
                buffoffset++;
                break;
            default:
                break;
        } //switch end
    } // while end
    item++; 
    return item;
}

//读取电话号码文件内容，并转为二维数组
uint16_t GetMemberItemCount(int8_t *pbuff, off_t file_size)
{
    uint16_t item = 0;
    uint8_t stepStatus = 0;
    uint8_t teloffset = 0;
    off_t buffoffset = 0;
    while((stepStatus < 3) && (buffoffset < file_size)) //读数据到文件最后
    {
        switch(stepStatus)
        {
            case 0: //初始化
                teloffset = 0;
                stepStatus = 1;
                break;
            case 1: //读号码
                if(*(pbuff+buffoffset) == 0x0A)
                {
                    buffoffset++;
                    break; 
                }
                if((*(pbuff+buffoffset) >= '0') && (*(pbuff+buffoffset) <= '9'))
                {
                    //增加指针值获取的
                    teloffset++;
                }
                if(*(pbuff+buffoffset) == ',')
                {
                    stepStatus = 2;   
                }
                
                buffoffset++;
                break;
            case 2://判断是否还有下一行
                if((*(pbuff+buffoffset) == 0x0A))
                {
                    if((buffoffset+1) < file_size) //不是文件尾
                    {
                        if((*(pbuff+buffoffset+1) >= '0') && (*(pbuff+buffoffset+1) <= '9'))
                        { //下一个字符是0x0A,再下一个字符是数字，认为还有新数据       
                            stepStatus = 0;
                            item++;         
                        }
                    }
                }
                buffoffset++;
                break;
            default:
                break;
        } //switch end
    } // while end 
   // item++;
    return item;
}

//获取电话号码的文件的有多少行电话号码
TEL *GetMemberItemContent(int8_t *pbuff, off_t file_size)
{
    uint16_t item = 0;
    uint8_t stepStatus = 0;
    uint8_t teloffset = 0;
    off_t buffoffset = 0;
    uint16_t totalItem =0;
    totalItem =  GetMemberItemCount(pbuff, file_size);  
    size_t mallocSize = (sizeof(TEL)) * totalItem;
    TEL *ptel = NULL;
    ptel = (TEL(*))malloc(mallocSize); 
    if(ptel == NULL)
    {
        printf("malloc ptel failse!\n");
        return 0;
    }
    memset(ptel, 0, sizeof(TEL) * totalItem);
    while((stepStatus < 3) && (buffoffset < file_size)) //读数据到文件最后
    {
        switch(stepStatus)
        {
            case 0: //初始化
                teloffset = 0;
                stepStatus = 1;
                break;
            case 1: //读号码
                if(*(pbuff+buffoffset) == 0x0A)
                {
                    buffoffset++;   
                    break; 
                }
                if((*(pbuff+buffoffset) >= '0') && (*(pbuff+buffoffset) <= '9'))
                {
                    //增加指针值获取的
                    if(teloffset < 11)//防越界，号码小于11位
                    {
                        (ptel+item)->tel[teloffset]  = *(pbuff+buffoffset);
                        teloffset++;
                    }
                    
                }
                if(*(pbuff+buffoffset) == ',')
                {
                    stepStatus = 2;   
                }
                
                buffoffset++;
                break;
            case 2://判断是否还有下一行
                if((*(pbuff+buffoffset) == 0x0A))
                {
                    if((buffoffset+1) < file_size) //不是文件尾
                    {
                        if((*(pbuff+buffoffset+1) >= '0') && (*(pbuff+buffoffset+1) <= '9'))
                        { //下一个字符是0x0A,再下一个字符是数字，认为还有新数据       
                            stepStatus = 0;
                            item++;         
                        }
                    }
                }
                buffoffset++;
                break;
            default:
                break;
        } //switch end
    } // while end
   // item++; 
    return ptel;
}

//返回匹配数量
//参数1：指向小票数据的指针
//参数2：指向烟条码数组
uint16_t MatchEAN13CODE(BILLINFO *pbill, YANINFO *pyaninfo)
{
    keyOrder = 0; //开始传输条码时，置0，开始累加
    int16_t result = 0;
    uint16_t billTotalItem = 0;
    billTotalItem = (pbill->totalItem); 
    //printf("%s: billTotalItem: %d\n", __func__, billTotalItem);
    uint16_t yanTotalItem = 0;
    uint16_t machItem = 0; //记录匹配数
    double billtotalPrice = pbill->totalPrice;
    double yantotalPrice = 0; 
    uint16_t itemCount =0; //记录匹配该条码的数量
    extern uint16_t quantity;
    yanTotalItem = quantity;   
    for(uint16_t billItem=0; billItem<billTotalItem; billItem++)
    {
        for(uint16_t yanItem=0; yanItem<yanTotalItem; yanItem++)
        {
            result = memcmp(((pbill->itemInfo)+billItem)->ean13Code, (pyaninfo+yanItem)->ean13, _EANCODEMAX);
            // for(uint16_t ii=0; ii<13; ii++)
            // {
            //     printf("%02x <====> %02x\n", ((pbill->itemInfo)+billItem)->ean13Code[ii], ((*pyaninfo)+yanItem)->ean13[ii]);
            // }
            if(result ==0) //如果匹配
            {   
                machItem++;
                itemCount = ((pbill->itemInfo)+billItem)->quantity;
                do
                { //至少循环一次
                    itemCount--;
                    for(uint8_t loop=0; loop<13; loop++)
                    {//将匹配的条码写入新的MSG结构体中，等待通过USBHID发送
                        if(((pbill->itemInfo)+billItem)->ean13Code[loop] == '\0') break; //条码小于13位时，提前结束循环
                        TransferUSBHIDKey(&USBHIDdat_MSG, ((pbill->itemInfo)+billItem)->ean13Code[loop]);                   
                    }                
                    TransferUSBHIDKey(&USBHIDdat_MSG, 0x17);    //确认键         
                    yantotalPrice += atof((const char*)((pyaninfo+yanItem))->price); //对烟的条码金额进行累加
                }while(itemCount > 0);
            }
             
        }//yanItem for end
    } //billItem for end
    double othertotalPrice = 0;   
    othertotalPrice = billtotalPrice - yantotalPrice;  //其他金额中含有小数点
    if(othertotalPrice > 0)
    {//发送其他金额数据
        MSG ttyS0_tmp;
        MSG ttyS0_dat;
        ttyS0_dat.fd = ttyS0FD;
        ttyS0_tmp.fd = ttyS0FD;
        ttyS0_dat.len = sprintf((char*)ttyS0_dat.buff, "%.2f", othertotalPrice);
        ttyS0_tmp.len = ttyS0_dat.len;
        for(uint8_t ii=0; ii<ttyS0_dat.len; ii++)
        {
            
            if((ttyS0_dat.buff[ii] == 0x2E) && (ttyS0_dat.buff[ii+1] == 0x30) && (ttyS0_dat.buff[ii+2] == 0x30)) break;
            
            TrasferMatchKey(&ttyS0_tmp, ttyS0_dat.buff[ii]);
          
        }
        TrasferMatchKey(&ttyS0_tmp, 0x17);//按下确认,发送函数中，已有延时
    } 
    return machItem;
}

//传输按键数据
uint16_t TrasferMatchKey(void *msg, int8_t dat)
{ 
    int8_t keyvalue=0;
    sem_post(&transferStartFlag);
    switch(dat)
    {
        case 0x2E:
            keyvalue = KEY_DOT;
            break;
        case 0x30:
            keyvalue = KEY_0;
            break;
        case 0x31:
            keyvalue = KEY_1;
            break;
        case 0x32:
            keyvalue = KEY_2;
            break;
        case 0x33:
            keyvalue = KEY_3;
            break;
        case 0x34:
            keyvalue = KEY_4;
            break;
        case 0x35:
            keyvalue = KEY_5;
            break;
        case 0x36:
            keyvalue = KEY_6;
            break;
        case 0x37:
            keyvalue = KEY_7;
            break;
        case 0x38:
            keyvalue = KEY_8;
            break;
        case 0x39:
            keyvalue = KEY_9;
            break;
        case 0x17:
            keyvalue = KEY_CONFIRM;
            break;
        default:
            break;
    }
    
    GenerateKeyPressMsg(msg, keyvalue);
    TTYtransferDat(msg);
    int16_t timeout = 88; //原值90   
    do
    {      
       
       usleep(1000); //延时1ms
       timeout--;   
       if(timeout <=0)
       {    
        time_t tim = time(NULL);
        struct tm *tm = localtime(&tim);
        struct timeval tv;
        gettimeofday(&tv, NULL);   
        printf("[%02d:%02d:%02d.%03ld] linux -->>>>> mapai # Mapai RESPONDS time out! Transfer continue ...\n",\
        tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec/1000);
        sem_post(&transferAllowFlag);
       }
    } while (sem_trywait(&transferAllowFlag) == -1);
    
    GenerateKeyReleaseMsg(msg, keyvalue);   
    TTYtransferDat(msg);
    if(keyvalue == KEY_CONFIRM)
   {
        keyvalue = 0;
       usleep(700000); //确认后延时700ms      
   } else usleep(28000); //其他键延时28ms
   sem_trywait(&transferStartFlag);
    return 0;
}

//分析按键数据
void AnalysisKEYBOARDCommand(uint8_t *pdat)
{
    uint16_t ii = 0;
    memset(&keyCommand, 0, sizeof(keyCommand));
    keyCommand.head = *(pdat+0);
    keyCommand.len = (uint16_t)*(pdat+1);
    keyCommand.len <<= 8;
    keyCommand.len |= (uint16_t)*(pdat+2);
    keyCommand.order = *(pdat+3);
    keyCommand.mode = *(pdat+4);
    for(ii=0; ii<keyCommand.len; ii++) //有效数据，包括前面包序和类型2个字节，不包含结束符0x03和校验位
    {
        keyCommand.dat[ii] = *(pdat+3+ii);
    }
    keyCommand.checksum = *(pdat+4+keyCommand.len);
}


//生成获取USB HID 芯片版本、状态等信息
void GenerateUSBHIDCmdGetInfoMsg(void *msg)
{
    MSG *pmsg = (MSG*)msg;
    USBHID usbKey;
    usbKey.head1 = 0x57;
    usbKey.head2 = 0xab;
    usbKey.addr = 0x00;
    usbKey.command = 0x01;
    usbKey.len = 0x00;
    usbKey.sum = 0x03;
    pmsg->len = 0x06;
    // CP usbhid DAT TO MSG->BUFF
    uint8_t *pusbKey = (uint8_t*)&usbKey;
    for(uint8_t ii=0; ii<5; ii++) //复制前5个字节，中间有DAT[]区，要跳过
    {
        pmsg->buff[ii] = *(pusbKey+ii);
    }
    pmsg->buff[5] = usbKey.sum;
}

//生成USB HID 复位信息
void GenerateUSBHIDResetMsg(void *msg)
{
    MSG *pmsg = (MSG*)msg;
    USBHID usbKey;
    usbKey.head1 = 0x57;
    usbKey.head2 = 0xab;
    usbKey.addr = 0x00;
    usbKey.command = 0x0F;
    usbKey.len = 0x00;
    usbKey.sum = 0x11;
    pmsg->len = 0x06;
    // CP usbhid DAT TO MSG->BUFF
    uint8_t *pusbKey = (uint8_t*)&usbKey;
    for(uint8_t ii=0; ii<5; ii++)//复制前5个字节，中间有DAT[]区，要跳过
    {
        pmsg->buff[ii] = *(pusbKey+ii);
    }
    pmsg->buff[5] = usbKey.sum;
}

//向码牌机发送会员号码, 参数1，数据，  参数2，那个会员
void TransferMembers(void *msg, uint16_t order)
{
    uint16_t telitem = GetMemberOrder();

    for(uint16_t ii=0; ii<11; ii++)
    {
         
        TransferUSBHIDKey(msg, (ptel+telitem)->tel[ii]);
    }
    TransferUSBHIDKey(msg, 0x17);
    
}